package nconv.convert;

/**
 * Created by xiaobyu on 4/25/2016.
 */
public class WikiFormatUtils {

    public static interface FmtWikiI extends Comparable<FmtWikiI>{
        public int getPriority();

        public void handle(StringBuilder start, StringBuilder end, String markContent);

        public boolean accept(FmtWikiI target);
    }

    public static abstract class FmtWiki implements FmtWikiI {
        public boolean accept(FmtWikiI target) {
            return true;
        }

        public String toString() {
            return "( Name: " + getClass().getSimpleName() + ", Priority: " + getPriority() + ")";
        }

        public int compareTo(FmtWikiI o) {
            return getPriority() - o.getPriority();
        }
    }

    private static final int PRIORITY_NOWIKI = 0;
    private static final int PRIORITY_HEADING = 1000;
    private static final int PRIORITY_TEMPLATE = 2000;
    private static final int PRIORITY_HYPERLINK = 3000;
    private static final int PRIORITY_LIST_LABEL = 4000;
    private static final int PRIORITY_LIST_SYMBOL = 5000;
    private static final int PRIORITY_ITALIC = 6000;
    private static final int PRIORITY_BOLD = 7000;
    private static final int PRIORITY_INTERNAL_LINK = 8000;
    private static final int PRIORITY_BOOKMARK = 9000;

    public static class FmtNoWiki extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_NOWIKI;
        }

        @Override
        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, "<nowiki>");
            end.append("</nowiki>");
        }

        public boolean accept(FmtWikiI target) {
            return false;
        }
    }

    public static class FmtHeading extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_HEADING;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, markContent);
            end.append(markContent);
        }

        public boolean accept(FmtWikiI target) {
            return target.getPriority() == PRIORITY_BOOKMARK;
        }

        public int compareTo(FmtWikiI o) {
            if (o.getPriority() == PRIORITY_BOOKMARK) {
                return 1;
            }
            return super.compareTo(o);
        }
    }

    public static class FmtListSymbol extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_LIST_SYMBOL;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, markContent + " ");
        }

        public int compareTo(FmtWikiI o) {
            if (o.getPriority() == PRIORITY_BOOKMARK) {
                return 1;
            }
            return super.compareTo(o);
        }
    }

    public static class FmtListLabel extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_LIST_LABEL;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, "'''" + markContent + "''' ");
        }

        public boolean accept(FmtWikiI target) {
            return target.getPriority() == PRIORITY_BOOKMARK;
        }
    }

    public static class FmtBookmark extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_BOOKMARK;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, "<span id='" + markContent + "'>");
            end.append("</span>");
        }

        public int compareTo(FmtWikiI o) {
            if (o.getPriority() == PRIORITY_HEADING
                    || o.getPriority() == PRIORITY_LIST_SYMBOL) {
                return -1;
            }
            return super.compareTo(o);
        }
    }

    public static class FmtItalic extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_ITALIC;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, "''");
            end.append("''");
        }

        public boolean accept(FmtWikiI target) {
            return target.getPriority() != getPriority();
        }
    }

    public static class FmtBold extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_BOLD;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, "'''");
            end.append("'''");
        }

        public boolean accept(FmtWikiI target) {
            return target.getPriority() != getPriority();
        }
    }

    public static class FmtHyperLink extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_HYPERLINK;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, "[" + markContent + " ");
            end.append("]");
        }

        public boolean accept(FmtWikiI target) {
            return target.getPriority() != getPriority();
        }
    }

    public static class FmtInternalLink extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_INTERNAL_LINK;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, "[[#" + markContent + "|");
            end.append("]]");
        }

        public boolean accept(FmtWikiI target) {
            return target.getPriority() != getPriority();
        }
    }

    public static class FmtTemplate extends FmtWiki {

        @Override
        public int getPriority() {
            return PRIORITY_TEMPLATE;
        }

        public void handle(StringBuilder start, StringBuilder end, String markContent) {
            start.insert(0, "{{" + markContent + "|");
            end.append("}}");
        }

        public boolean accept(FmtWikiI target) {
            return false;
        }
    }

    public static final FmtWikiI fmtNoWiki = new FmtNoWiki();
    public static final FmtWikiI fmtHeading = new FmtHeading();
    public static final FmtWikiI fmtListSymbol = new FmtListSymbol();
    public static final FmtWikiI fmtListLabel = new FmtListLabel();
    public static final FmtWikiI fmtBookmark = new FmtBookmark();
    public static final FmtWikiI fmtItalic = new FmtItalic();
    public static final FmtWikiI fmtBold = new FmtBold();
    public static final FmtWikiI fmtHyperLink = new FmtHyperLink();
    public static final FmtWikiI fmtInternalLink = new FmtInternalLink();
    public static final FmtWikiI fmtTemplate = new FmtTemplate();

}
